/*
*  SkyOpenALContext.h
*  
*
*  Created by Alexander Trutchenko on 11/02/12.
*  Copyright 2012 Free Team. All rights reserved.
*
*/

#ifndef __Sky_OpenALContext_h__
#define __Sky_OpenALContext_h__

#include "SkyOpenALInclude.h"

#include "stdlib.h"

#include <set>
#include <map>
#include <vector>

namespace sky {

typedef std::map<ALCenum, int>  SkyALContextAttributes;

////////////////////////////////////////////////////////
//
/** SkyOpenALContext
*  
*/
////////////////////////////////////////////////////////

class SkySoundEngine;
class SkyOpenALListener;
class SkyBufferManager;
class SkySoundSource;
class SkyOpenALContext
{
friend class SkySoundEngine;
friend class SkySoundSource;

typedef std::set<std::string> Keys;
typedef std::vector<SkySoundSource*> Sources; 
typedef std::set<int> LockedIDs;

protected:
	bool _isCurrent;

	//OpenAL version
	int _magorVersion;
	int _minorVersion;

	SkyBufferManager* _bufferManager;
	SkyOpenALListener* _listener; // listener for this context

	ALCdevice* _outputDevice; // device for working with OpenAL
	ALCcontext* _context; // context for working with OpenAL

	//buffers
	Keys _buffers;
	Keys _compressedFiles;

	//Sources
	Sources _sources;

	//Sound source id's
	int _cursorOfSoundID;
	bool _checkLocked;
	LockedIDs _lockedIDs;

protected:
	virtual ~SkyOpenALContext();

	virtual bool init(SkyBufferManager* bufferManager, 
					  ALCdevice* outputDevice, 
					  int magorVersion, 
					  int minorVersion);

public:
	SkyOpenALContext();

public:
	virtual void setIsCurrent(bool isCurrent);
	virtual bool isValid() const { return (_outputDevice != NULL && _context != NULL); }
	virtual void attributes(SkyALContextAttributes& attributes) const;

	virtual void pause();
	virtual void resume();

//Preload/unload context-dependent effects and files (unloads with context) 
		/* Preload compressed files */
	bool preloadCompressedFile(const char* file);
		/* Unload compressed files */
	void unloadCompressedFile(const char* file);
		/* Preload and uncompress(decode with decoders) file and move to OpenAL buffer */ 
	bool preloadFileToBuffer(const char* file);
		/* Free OpenAL buffer from the file */
	void unloadFileFromBuffer(const char* file);

// Global settings
	ALenum distanceModel() const;
	void setDistanceModel(ALenum model); // default is AL_INVERSE_DISTANCE_CLAMPED
	float speedOfSound() const;
	void setSpeedOfSound(float speedOfSound); // default is 343.3 m/s
	float doplerFactor() const;
	void setDoplerFactor(float doplerFactor); //default is 1.0
	//For OpenAL 1.1 only
	float doplerVelocity() const;
	void setDoplerVelocity(float doplerVelocity); //default is 1.0

protected:
	virtual void update(float dt) {;}
	void addSource(SkySoundSource* source);
	void removeSource(SkySoundSource* source);
	int generateSoundID();
	void lockID(int soundID);
	void unlockID(int soundID);

private:

}; //end class SkyOpenALContext

} // namespace sky

#endif //__Sky_OpenALContext_h__
